#ifndef RMemoryStream_H
#define RMemoryStream_H

// Riccsson include.
#include <System/RCore.h>
#include <System/Object.h>
#include <System/String.h>
#include <System/Array.h>
#include <System/IO/Stream.h>

// C# include.
#include <Defines.h>

namespace Riccsson
{
	namespace System
	{
		namespace IO
		{
			class CancellationToken;

			/// <summary>
			///     Provides a generic view of a sequence of bytes.
			/// </summary>
			class MemoryStream
				: public Stream
			{
				//REGISTER_CLASS(MemoryStream)

				PROP3(MemoryStream, int, Capacity)

				// Summary:
				//     Initializes a new instance of the System.IO.MemoryStream class with an expandable
				//     capacity initialized to zero.
				public: MemoryStream()
					: PROP3_INIT(MemoryStream, Capacity)
				{

				}

				//
				// Summary:
				//     Initializes a new non-resizable instance of the System.IO.MemoryStream class
				//     based on the specified byte array.
				//
				// Parameters:
				//   buffer:
				//     The array of unsigned bytes from which to create the current stream.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
				public: MemoryStream(Array<byte>* buffer)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Initializes a new instance of the System.IO.MemoryStream class with an expandable
				//     capacity initialized as specified.
				//
				// Parameters:
				//   capacity:
				//     The initial size of the internal array in bytes.
				//
				// Exceptions:
				//   System.ArgumentOutOfRangeException:
				//     capacity is negative.
				public: MemoryStream(int capacity)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Initializes a new non-resizable instance of the System.IO.MemoryStream class
				//     based on the specified byte array with the System.IO.MemoryStream.CanWrite
				//     property set as specified.
				//
				// Parameters:
				//   buffer:
				//     The array of unsigned bytes from which to create this stream.
				//
				//   writable:
				//     The setting of the System.IO.MemoryStream.CanWrite property, which determines
				//     whether the stream supports writing.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				public: MemoryStream(Array<byte>* buffer, bool writable)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Initializes a new non-resizable instance of the System.IO.MemoryStream class
				//     based on the specified region (index) of a byte array.
				//
				// Parameters:
				//   buffer:
				//     The array of unsigned bytes from which to create this stream.
				//
				//   index:
				//     The index into buffer at which the stream begins.
				//
				//   count:
				//     The length of the stream in bytes.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     index or count is less than zero.
				//
				//   System.ArgumentException:
				//     The buffer length minus index is less than count.
				public: MemoryStream(Array<byte>* buffer, int index, int count)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Initializes a new non-resizable instance of the System.IO.MemoryStream class
				//     based on the specified region of a byte array, with the System.IO.MemoryStream.CanWrite
				//     property set as specified.
				//
				// Parameters:
				//   buffer:
				//     The array of unsigned bytes from which to create this stream.
				//
				//   index:
				//     The index in buffer at which the stream begins.
				//
				//   count:
				//     The length of the stream in bytes.
				//
				//   writable:
				//     The setting of the System.IO.MemoryStream.CanWrite property, which determines
				//     whether the stream supports writing.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     index or count are negative.
				//
				//   System.ArgumentException:
				//     The buffer length minus index is less than count.
				public: MemoryStream(Array<byte>* buffer, int index, int count, bool writable)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Initializes a new instance of the System.IO.MemoryStream class based on the
				//     specified region of a byte array, with the System.IO.MemoryStream.CanWrite
				//     property set as specified, and the ability to call System.IO.MemoryStream.GetBuffer()
				//     set as specified.
				//
				// Parameters:
				//   buffer:
				//     The array of unsigned bytes from which to create this stream.
				//
				//   index:
				//     The index into buffer at which the stream begins.
				//
				//   count:
				//     The length of the stream in bytes.
				//
				//   writable:
				//     The setting of the System.IO.MemoryStream.CanWrite property, which determines
				//     whether the stream supports writing.
				//
				//   publiclyVisible:
				//     true to enable System.IO.MemoryStream.GetBuffer(), which returns the unsigned
				//     byte array from which the stream was created; otherwise, false.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     index or count is negative.
				//
				//   System.ArgumentException:
				//     The buffer length minus index is less than count.
				public: MemoryStream(Array<byte>* buffer, int index, int count, bool writable, bool publiclyVisible)
					: PROP3_INIT(MemoryStream, Capacity)
				{
					throw;
				}


				// Summary:
				//     Gets a value indicating whether the current stream supports reading.
				//
				// Returns:
				//     true if the stream is open.
				public: override PROP3_GET(bool, CanRead)
				{
					throw;
				}

				//
				// Summary:
				//     Gets a value indicating whether the current stream supports seeking.
				//
				// Returns:
				//     true if the stream is open.
				public: override PROP3_GET(bool, CanSeek)
				{
					throw;
				}

				//
				// Summary:
				//     Gets a value indicating whether the current stream supports writing.
				//
				// Returns:
				//     true if the stream supports writing otherwise, false.
				public: override PROP3_GET(bool, CanWrite)
				{
					throw;
				}

				//
				// Summary:
				//     Gets or sets the number of bytes allocated for this stream.
				//
				// Returns:
				//     The length of the usable portion of the buffer for the stream.
				//
				// Exceptions:
				//   System.ArgumentOutOfRangeException:
				//     A capacity is set that is negative or less than the current length of the
				//     stream.
				//
				//   System.ObjectDisposedException:
				//     The current stream is closed.
				//
				//   System.NotSupportedException:
				//     set is invoked on a stream whose capacity cannot be modified.
				public: virtual PROP3_GET(int, Capacity)
				{
					throw;
				}
				public: virtual PROP3_SET(int, Capacity)
				{
					throw;
				}

				//
				// Summary:
				//     Gets the length of the stream in bytes.
				//
				// Returns:
				//     The length of the stream in bytes.
				//
				// Exceptions:
				//   System.ObjectDisposedException:
				//     The stream is closed.
				public: override PROP3_GET(long, Length)
				{
					throw;
				}

				//
				// Summary:
				//     Gets or sets the current position within the stream.
				//
				// Returns:
				//     The current position within the stream.
				//
				// Exceptions:
				//   System.ArgumentOutOfRangeException:
				//     The position is set to a negative value or a value greater than System.Int32.MaxValue.
				//
				//   System.ObjectDisposedException:
				//     The stream is closed.
				public: override PROP3_GET(long, Position)
				{
					throw;
				}
				public: override PROP3_SET(long, Position)
				{
					throw;
				}

				// Summary:
				//     Asynchronously reads all the bytes from the current stream and writes them
				//     to another stream, using a specified buffer size and cancellation token.
				//
				// Parameters:
				//   destination:
				//     The stream to which the contents of the current stream will be copied.
				//
				//   bufferSize:
				//     The size, in bytes, of the buffer. This value must be greater than zero.
				//
				//   cancellationToken:
				//     The token to monitor for cancellation requests.
				//
				// Returns:
				//     A task that represents the asynchronous copy operation.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     destination is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     buffersize is negative or zero.
				//
				//   System.ObjectDisposedException:
				//     Either the current stream or the destination stream is disposed.
				//
				//   System.NotSupportedException:
				//     The current stream does not support reading, or the destination stream does
				//     not support writing.
				public: override GC_PTR<Task> CopyToAsync(Stream* destination, int bufferSize, CancellationToken* cancellationToken)
				{
					throw;
				}

				//
				// Summary:
				//     Releases the unmanaged resources used by the System.IO.MemoryStream class
				//     and optionally releases the managed resources.
				//
				// Parameters:
				//   disposing:
				//     true to release both managed and unmanaged resources false to release only
				//     unmanaged resources.
				protected: override void Dispose(bool disposing)
				{
					throw;
				}

				//
				// Summary:
				//     Overrides the System.IO.Stream.Flush() method so that no action is performed.
				public: override void Flush()
				{
					throw;
				}

				//
				// Summary:
				//     Asynchronously clears all buffers for this stream, and monitors cancellation
				//     requests.
				//
				// Parameters:
				//   cancellationToken:
				//     The token to monitor for cancellation requests.
				//
				// Returns:
				//     A task that represents the asynchronous flush operation.
				//
				// Exceptions:
				//   System.ObjectDisposedException:
				//     The stream has been disposed.
				//[ComVisible(false)]
				public: override GC_PTR<Task> FlushAsync(CancellationToken* cancellationToken)
				{
					throw;
				}

				//
				// Summary:
				//     Returns the array of unsigned bytes from which this stream was created.
				//
				// Returns:
				//     The byte array from which this stream was created, or the underlying array
				//     if a byte array was not provided to the System.IO.MemoryStream constructor
				//     during construction of the current instance.
				//
				// Exceptions:
				//   System.UnauthorizedAccessException:
				//     The MemoryStream instance was not created with a publicly visible buffer.
				//[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
				public: virtual GC_PTR<Array<byte>> GetBuffer()
				{
					throw;
				}

				//
				// Summary:
				//     Reads a block of bytes from the current stream and writes the data to a buffer.
				//
				// Parameters:
				//   buffer:
				//     When this method returns, contains the specified byte array with the values
				//     between offset and (offset + count - 1) replaced by the characters read from
				//     the current stream.
				//
				//   offset:
				//     The zero-based byte offset in buffer at which to begin storing data from
				//     the current stream.
				//
				//   count:
				//     The maximum number of bytes to read.
				//
				// Returns:
				//     The total number of bytes written into the buffer. This can be less than
				//     the number of bytes requested if that number of bytes are not currently available,
				//     or zero if the end of the stream is reached before any bytes are read.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     offset or count is negative.
				//
				//   System.ArgumentException:
				//     offset subtracted from the buffer length is less than count.
				//
				//   System.ObjectDisposedException:
				//     The current stream instance is closed.
				public: override int Read(Array<byte>* buffer, int offset, int count)
				{
					throw;
				}

				//
				// Summary:
				//     Asynchronously reads a sequence of bytes from the current stream, advances
				//     the position within the stream by the number of bytes read, and monitors
				//     cancellation requests.
				//
				// Parameters:
				//   buffer:
				//     The buffer to write the data into.
				//
				//   offset:
				//     The byte offset in buffer at which to begin writing data from the stream.
				//
				//   count:
				//     The maximum number of bytes to read.
				//
				//   cancellationToken:
				//     The token to monitor for cancellation requests. The default value is System.Threading.CancellationToken.None.
				//
				// Returns:
				//     A task that represents the asynchronous read operation. The value of the
				//     TResult parameter contains the total number of bytes read into the buffer.
				//     The result value can be less than the number of bytes requested if the number
				//     of bytes currently available is less than the requested number, or it can
				//     be 0 (zero) if the end of the stream has been reached.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     offset or count is negative.
				//
				//   System.ArgumentException:
				//     The sum of offset and count is larger than the buffer length.
				//
				//   System.NotSupportedException:
				//     The stream does not support reading.
				//
				//   System.ObjectDisposedException:
				//     The stream has been disposed.
				//
				//   System.InvalidOperationException:
				//     The stream is currently in use by a previous read operation.
				//[ComVisible(false)]
				public: override GC_PTR<Collections::Generic::Task<int>> ReadAsync(Array<byte>* buffer, int offset, int count, CancellationToken* cancellationToken)
				{
					throw;
				}

				//
				// Summary:
				//     Reads a byte from the current stream.
				//
				// Returns:
				//     The byte cast to a System.Int32, or -1 if the end of the stream has been
				//     reached.
				//
				// Exceptions:
				//   System.ObjectDisposedException:
				//     The current stream instance is closed.
				public: override int ReadByte()
				{
					throw;
				}

				//
				// Summary:
				//     Sets the position within the current stream to the specified value.
				//
				// Parameters:
				//   offset:
				//     The new position within the stream. This is relative to the loc parameter,
				//     and can be positive or negative.
				//
				//   loc:
				//     A value of type System.IO.SeekOrigin, which acts as the seek reference point.
				//
				// Returns:
				//     The new position within the stream, calculated by combining the initial reference
				//     point and the offset.
				//
				// Exceptions:
				//   System.IO.IOException:
				//     Seeking is attempted before the beginning of the stream.
				//
				//   System.ArgumentOutOfRangeException:
				//     offset is greater than System.Int32.MaxValue.
				//
				//   System.ArgumentException:
				//     There is an invalid System.IO.SeekOrigin. -or-offset caused an arithmetic
				//     overflow.
				//
				//   System.ObjectDisposedException:
				//     The current stream instance is closed.
				public: override long Seek(long offset, SeekOrigin* loc)
				{
					throw;
				}

				//
				// Summary:
				//     Sets the length of the current stream to the specified value.
				//
				// Parameters:
				//   value:
				//     The value at which to set the length.
				//
				// Exceptions:
				//   System.NotSupportedException:
				//     The current stream is not resizable and value is larger than the current
				//     capacity.-or- The current stream does not support writing.
				//
				//   System.ArgumentOutOfRangeException:
				//     value is negative or is greater than the maximum length of the System.IO.MemoryStream,
				//     where the maximum length is(System.Int32.MaxValue - origin), and origin is
				//     the index into the underlying buffer at which the stream starts.
				public: override void SetLength(long value)
				{
					throw;
				}

				//
				// Summary:
				//     Writes the stream contents to a byte array, regardless of the System.IO.MemoryStream.Position
				//     property.
				//
				// Returns:
				//     A new byte array.
				public: virtual GC_PTR<Array<byte>> ToArray()
				{
					throw;
				}

				//
				// Summary:
				//     Writes a block of bytes to the current stream using data read from a buffer.
				//
				// Parameters:
				//   buffer:
				//     The buffer to write data from.
				//
				//   offset:
				//     The zero-based byte offset in buffer at which to begin copying bytes to the
				//     current stream.
				//
				//   count:
				//     The maximum number of bytes to write.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.NotSupportedException:
				//     The stream does not support writing. For additional information see System.IO.Stream.CanWrite.-or-
				//     The current position is closer than count bytes to the end of the stream,
				//     and the capacity cannot be modified.
				//
				//   System.ArgumentException:
				//     offset subtracted from the buffer length is less than count.
				//
				//   System.ArgumentOutOfRangeException:
				//     offset or count are negative.
				//
				//   System.IO.IOException:
				//     An I/O error occurs.
				//
				//   System.ObjectDisposedException:
				//     The current stream instance is closed.
				public: override void Write(Array<byte>* buffer, int offset, int count)
				{
					throw;
				}

				//
				// Summary:
				//     Asynchronously writes a sequence of bytes to the current stream, advances
				//     the current position within this stream by the number of bytes written, and
				//     monitors cancellation requests.
				//
				// Parameters:
				//   buffer:
				//     The buffer to write data from.
				//
				//   offset:
				//     The zero-based byte offset in buffer from which to begin copying bytes to
				//     the stream.
				//
				//   count:
				//     The maximum number of bytes to write.
				//
				//   cancellationToken:
				//     The token to monitor for cancellation requests. The default value is System.Threading.CancellationToken.None.
				//
				// Returns:
				//     A task that represents the asynchronous write operation.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     buffer is null.
				//
				//   System.ArgumentOutOfRangeException:
				//     offset or count is negative.
				//
				//   System.ArgumentException:
				//     The sum of offset and count is larger than the buffer length.
				//
				//   System.NotSupportedException:
				//     The stream does not support writing.
				//
				//   System.ObjectDisposedException:
				//     The stream has been disposed.
				//
				//   System.InvalidOperationException:
				//     The stream is currently in use by a previous write operation.
				//[ComVisible(false)]
				public: override GC_PTR<Task> WriteAsync(Array<byte>* buffer, int offset, int count, CancellationToken* cancellationToken)
				{
					throw;
				}

				//
				// Summary:
				//     Writes a byte to the current stream at the current position.
				//
				// Parameters:
				//   value:
				//     The byte to write.
				//
				// Exceptions:
				//   System.NotSupportedException:
				//     The stream does not support writing. For additional information see System.IO.Stream.CanWrite.-or-
				//     The current position is at the end of the stream, and the capacity cannot
				//     be modified.
				//
				//   System.ObjectDisposedException:
				//     The current stream is closed.
				public: override void WriteByte(byte value)
				{
					throw;
				}

				//
				// Summary:
				//     Writes the entire contents of this memory stream to another stream.
				//
				// Parameters:
				//   stream:
				//     The stream to write this memory stream to.
				//
				// Exceptions:
				//   System.ArgumentNullException:
				//     stream is null.
				//
				//   System.ObjectDisposedException:
				//     The current or target stream is closed.
				public: virtual void WriteTo(Stream* stream)
				{
					throw;
				}
			};
		}
	}
}
#endif //EXTENSIONS_H